import { requestFrame } from "utils-lib-js";
import { IDelay, IntervalId, IHandle, TimerItem, Timers, Timer, ITimerManagerOptions } from "./types"
// 默认定时器配置
export const defaultOptions: ITimerManagerOptions = {
    type: "interval",
    autoStop: true
};
// 定时器管理器
export class TimerManager {
    __id: number = 0;
    timers: Timers = {};
    readonly fixString = "#@$&*";
    readonly opts: ITimerManagerOptions;
    constructor(opts?: Partial<ITimerManagerOptions>) {
        // 使用默认选项填充缺失的属性
        this.opts = { ...defaultOptions, ...opts };
    }
    // 添加定时器项
    add(handle: IHandle, delay: IDelay = 0) {
        // 初始化指定延迟的定时器集合
        this.initDelay(delay);
        // 将定时器项推入定时器集合中
        return this.pushTimer(handle, delay);
    }
    // 删除定时器项
    delete(timer: TimerItem) {
        const { id, delay } = timer;
        const { timers } = this;
        if (delay && timers[delay]?.handles) timers[delay].handles = timers[delay].handles.filter((it) => it.id !== id);
    }
    // 停止并清除所有定时器
    clear() {
        const { timers } = this;
        Object.keys(timers).forEach((d) => this.stopTimer(timers[d]));
        this.timers = {};
    }
    // 将定时器项推入定时器集合中
    private pushTimer(handle: IHandle, delay: IDelay) {
        const { timers } = this;
        const __info = {
            id: this.getId(),
            handle,
            delay,
        };
        timers[delay].handles.push(__info);
        return __info;
    }
    // 初始化指定延迟的定时器集合
    private initDelay(delay: IDelay) {
        const { timers } = this;
        let timer = timers[delay];
        if (timer) return;
        // 创建新的定时器集合，并启动定时器
        timers[delay] = {
            intervalId: null,
            handles: [],
            delay,
        };
        this.startTimer(timers[delay]);
    }
    // 启动指定延迟的定时器
    startTimer(timer: Timer) {
        if (timer?.intervalId) this.stopTimer(timer)
        timer.intervalId = this.delayHandle(() => {
            this.autoStopTimer(timer)
            timer.handles.forEach((it) => it.handle());
        }, timer.delay);
    }
    // 停止指定延迟的定时器
    stopTimer(timer: Timer) {
        const { intervalId } = timer
        if (this.isFrame()) (intervalId as Function)();
        else clearInterval(intervalId as IntervalId);
    }
    // 自动释放定时器资源，根据当前定时器的handles长度判断
    private autoStopTimer(timer: Timer) {
        const { opts: { autoStop }, timers } = this
        const { delay } = timer
        if (autoStop && timer.handles.length <= 0) {
            this.stopTimer(timer)
            timers[delay] = null
        }
    }
    // 根据定时器返回延迟处理句柄
    delayHandle(handle: IHandle, delay: IDelay) {
        // 如果是帧定时器，则使用requestFrame方法，否则使用setInterval
        if (this.isFrame()) return requestFrame(handle, delay);
        else return setInterval(handle, delay);
    }
    // 判断是否为帧定时器
    isFrame = () => this.opts.type === "frame";
    // 获取唯一的定时器项id
    private getId() {
        return `${this.fixString}-${++this.__id}`;
    }
}

export default TimerManager;
